#ifndef PACKAGEREQUIREMENTS_H
#define PACKAGEREQUIREMENTS_H

#include "list.h"
#include "hashtable.h"
using namespace Library;

namespace PackageManagement
{

class PackageRequirement
{
	public:	
					PackageRequirement(pPackage	package, uint32	version);
					~PackageRequirement();

		pPackage	getPackage();
		uint32		getVersion();

		bool8		isRequirementSatisfied();
		bool8		isRequirementSatisfiedWithDownload();
		bool8		operator==(PackageRequirement & rvalue);

	protected:
		pPackage	m_package;
		uint32		m_version;

	// prohibited
	private:
		PackageRequirement();
		PackageRequirement(PackageRequirement &);
		PackageRequirement & operator=(PackageRequirement &);
};


class PackageRequirements
{
	public:
					PackageRequirements();
					~PackageRequirements();

		bool8		build(pPackageMgr packageManager);
		void		clean();

		ListIterator<pPackageRequirement> * requirementsOf(const String&);

	protected:
		class TableEntry;
		typedef HashTable<TableEntry *>				RequiresTable;
		typedef HashTable<TableEntry *> *			pRequiresTable;
		typedef HashTableIterator<TableEntry *>		RequiresTableIterator;
		typedef HashTableIterator<TableEntry *> *	pRequiresTableIterator;

		pRequiresTable		m_requiresTable;

	// prohibited
	private:
		PackageRequirements(PackageRequirements &);
		PackageRequirements & operator=(PackageRequirements &);
};

class PackageRequirements::TableEntry
{
	public:
					TableEntry(pPackage package);
					~TableEntry();

		bool8		buildRequiresList(pRequiresTable requiresTable);

		List<pPackageRequirement> *	requiresList();

	protected:
		pPackage					m_package;
		List<pPackageRequirement> *	m_requiresList;

	// prohibited
	private:
		TableEntry();
		TableEntry(TableEntry &);
		TableEntry & operator=(TableEntry &);
};


//============================================================================

inline
PackageRequirement::PackageRequirement(pPackage package, uint32 version)
{
	m_package = package;
	m_version = version;
}

inline
PackageRequirement::~PackageRequirement()
{
}

inline pPackage
PackageRequirement::getPackage()
{
	return m_package;
}

inline uint32
PackageRequirement::getVersion()
{
	return m_version;
}

inline bool8
PackageRequirement::isRequirementSatisfied()
{
	return (bool8)(m_package->getLocalVersion() >= getVersion());
}

inline bool8
PackageRequirement::isRequirementSatisfiedWithDownload()
{
	return (bool8)(m_package->getServerVersion() >= getVersion());
}

inline bool8
PackageRequirement::operator==(PackageRequirement & rvalue)
{
	return (bool8)(m_package == rvalue.m_package);
}

}; // namespace PackageManagement

#endif
